package org.zebra.logging.aspect;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.zebra.logging.annotation.Log;
import org.zebra.logging.util.LoggingUtil;

/**
 * 操作日志记录处理
 *
 * @author zb
 */
@Slf4j
@Aspect
public class LogAspect {

    /**
     * 处理请求前执行
     *
     * @param controllerLog log对象
     * @param joinPoint     切面对象
     */
    @Before(value = "@annotation(controllerLog)")
    public void doBefore(JoinPoint joinPoint, Log controllerLog) {
        LoggingUtil.doBefore();
    }

    /**
     * 处理完请求后执行
     *
     * @param controllerLog log对象
     * @param jsonResult    结果对象
     * @param joinPoint     切点
     */
    @AfterReturning(pointcut = "@annotation(controllerLog)", returning = "jsonResult")
    public void doAfterReturning(JoinPoint joinPoint, Log controllerLog, Object jsonResult) {
        handleLog(joinPoint, controllerLog, null, jsonResult);
    }

    /**
     * 拦截异常操作
     *
     * @param controllerLog log对象
     * @param joinPoint     切点
     * @param e             异常
     */
    @AfterThrowing(value = "@annotation(controllerLog)", throwing = "e")
    public void doAfterThrowing(JoinPoint joinPoint, Log controllerLog, Exception e) {
        handleLog(joinPoint, controllerLog, e, null);
    }

    protected void handleLog(final JoinPoint joinPoint, Log controllerLog, final Exception e, Object jsonResult) {
        LoggingUtil.doAfter(
                controllerLog.title(),
                controllerLog.module(),
                controllerLog.businessType(),
                joinPoint.getTarget(),
                ((MethodSignature) joinPoint.getSignature()).getMethod(),
                joinPoint.getArgs(),
                jsonResult,
                controllerLog.isSaveRequestData(),
                controllerLog.isSaveResponseData(),
                controllerLog.excludeParamNames(),
                e);
    }
}
